import flet as ft
from pandas import DataFrame

import matplotlib
import matplotlib.pyplot as plt

from config import Location, Direction, Sensor, ProjectInfo
from data_tread import calculate_angle

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
# 设置中文显示正常
plt.rcParams['axes.unicode_minus'] = False

matplotlib.use("svg")


class SensorView(ft.DataTable):
    def __init__(self):
        self.Sensor_Col_List = ["sensor_code", "location", "direction", "angle_x", "angle_y", "angle_z", "acc_x",
                                "acc_y", "acc_z", "bat"]
        # 数据表中的中文列名

        self.Sensor_Col_CN_List = ["传感器编号", "传感器位置", "传感器方向", "x_角度", "y_角度", "z_角度", "x_加速度",
                                   "y_加速度", "z_加速度", "电池电量"]

        columns = [ft.DataColumn(ft.Text(col_name)) for col_name in self.Sensor_Col_CN_List]

        super().__init__(border=ft.border.all(2, "blue"),
                         vertical_lines=ft.BorderSide(1, "blue"),
                         horizontal_lines=ft.BorderSide(1, "blue"),
                         columns=columns)
        self.row_dict = {}  # 存储sensor_code和Row的关系

    def show_data(self, df_data: DataFrame):
        tb_sensor_code_list = list(self.row_dict.keys())
        df_sensor_code_list = df_data['sensor_code'].to_list()
        new_sensor_code_list = list(set(df_sensor_code_list) - set(tb_sensor_code_list))
        new_sensor_df_data = df_data[df_data['sensor_code'].isin(new_sensor_code_list)]
        self.create_row(new_sensor_df_data)
        for index, row in df_data.iterrows():
            sensor_code = row['sensor_code']
            tb_row = self.row_dict[sensor_code]
            for col in self.Sensor_Col_List[3:]:
                tb_row.cells[self.Sensor_Col_List.index(col)].content = ft.Text(str(row[col]))
        self.update()

    def create_row(self, df_data: DataFrame):
        """
        根据传入的DataFrame创建DataRow，并很如行字典和表格的行列表中
        """
        for index, row in df_data.iterrows():
            cells = []
            sensor_code = row['sensor_code']
            sensor = Sensor(sensor_code=sensor_code)
            ProjectInfo.sensor_info_dict[sensor_code] = sensor
            cells.append(ft.DataCell(ft.Text(sensor_code)))
            cells.append(
                ft.DataCell(MyDropdown(dropdown_list=Location, sensor_code=sensor_code, col_name="location"))
            )
            cells.append(
                ft.DataCell(MyDropdown(dropdown_list=Direction, sensor_code=sensor_code, col_name="direction"))
            )

            for col in self.Sensor_Col_List[3:]:
                cells.append(ft.DataCell(ft.Text(str(row[col]))))
            row = ft.DataRow(cells=cells)

            # 将表格的行信息添加表格的行列表和行信息字典中
            self.rows.append(row)
            self.row_dict[sensor_code] = row


angle_chart_data_series = [
    ft.LineChartData(
        data_points=ProjectInfo.a_agree_line_chart_list,
        color=ft.colors.BLUE,
        stroke_width=4,
    ),
    ft.LineChartData(
        data_points=ProjectInfo.b_agree_line_chart_list,
        color=ft.colors.GREEN,
        stroke_width=4,
    ),
    ft.LineChartData(
        data_points=ProjectInfo.total_line_chart_list,
        color=ft.colors.RED,
        stroke_width=8,
    )
]


class AngleChart(ft.LineChart):

    def __init__(self):
        self.x_axis_max = 100
        self.x_grid_num = 100
        self.x_axis_labels = []
        self.bottom_axis_list()
        super().__init__(
            data_series=angle_chart_data_series,
            horizontal_grid_lines=ft.ChartGridLines(
                interval=1, color=ft.colors.with_opacity(1, ft.colors.ON_SURFACE), width=1
            ),
            vertical_grid_lines=ft.ChartGridLines(
                interval=2, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1
            ),
            left_axis=ft.ChartAxis(
                labels=[
                    ft.ChartAxisLabel(
                        value=10,
                        label=ft.Text("10°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                    ft.ChartAxisLabel(
                        value=20,
                        label=ft.Text("20°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                    ft.ChartAxisLabel(
                        value=30,
                        label=ft.Text("30°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                    ft.ChartAxisLabel(
                        value=40,
                        label=ft.Text("40°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                    ft.ChartAxisLabel(
                        value=50,
                        label=ft.Text("50°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                    ft.ChartAxisLabel(
                        value=60,
                        label=ft.Text("60°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                    ft.ChartAxisLabel(
                        value=70,
                        label=ft.Text("70°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                    ft.ChartAxisLabel(
                        value=80,
                        label=ft.Text("80°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                    ft.ChartAxisLabel(
                        value=90,
                        label=ft.Text("90°", size=14, weight=ft.FontWeight.BOLD),
                    ),
                ],
                labels_size=40,
            ),
            bottom_axis=ft.ChartAxis(
                labels=self.x_axis_labels,
                labels_size=32,
            )
        )

    def bottom_axis_list(self):
        index = ProjectInfo.line_chart_index
        if index / self.x_axis_max > 0.95:
            self.x_axis_max = ((index * 1.4) // 100 + 1) * 100
            self.horizontal_grid_lines.interval = ProjectInfo.line_chart_index // 50
            self.x_axis_labels = []
            for i in range(self.x_axis_max // 10):
                self.x_axis_labels.append(ft.ChartAxisLabel(
                    value=(i + 1) * 10,
                    label=ft.Text(str(i * 10), size=14, weight=ft.FontWeight.BOLD),
                ))

    def update(self):
        super().update()
        self.data_series = angle_chart_data_series
        print("数据的长度是：", len(angle_chart_data_series[0].data_points))
        if ProjectInfo.line_chart_index > 40:
            self.horizontal_grid_lines.interval = ProjectInfo.line_chart_index // 40
        self.update()


acc_chart_data_series = [
    ft.LineChartData(
        data_points=ProjectInfo.acc_a_x_line_chart_list,
        color=ft.colors.BLUE,
        stroke_width=8,
    ),
    ft.LineChartData(
        data_points=ProjectInfo.acc_a_y_line_chart_list,
        color=ft.colors.GREEN,
        stroke_width=8,
    ),
    ft.LineChartData(
        data_points=ProjectInfo.acc_a_z_line_chart_list,
        color=ft.colors.GREY_50,
        stroke_width=4,
    ),
    ft.LineChartData(
        data_points=ProjectInfo.acc_b_x_line_chart_list,
        color=ft.colors.RED,
        stroke_width=8,
    ),
    ft.LineChartData(
        data_points=ProjectInfo.acc_b_y_line_chart_list,
        color=ft.colors.YELLOW,
        stroke_width=8,
    ),
    ft.LineChartData(
        data_points=ProjectInfo.acc_b_z_line_chart_list,
        color=ft.colors.AMBER_50,
        stroke_width=4,
    ),

]


class ACCChart(ft.LineChart):

    def __init__(self):
        super().__init__(
            data_series=acc_chart_data_series,
            horizontal_grid_lines=ft.ChartGridLines(
                interval=1, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1
            ),
            vertical_grid_lines=ft.ChartGridLines(
                interval=0.5, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1
            ),
        )

    def update(self):
        super().update()
        self.data_series = acc_chart_data_series
        if ProjectInfo.line_chart_index > 40:
            self.horizontal_grid_lines.interval = ProjectInfo.line_chart_index // 40
        else:
            self.horizontal_grid_lines.interval = 1
        self.update()


class MyDropdown(ft.Dropdown):
    def __init__(self, dropdown_list, sensor_code, col_name, default_value=None, **kwargs):
        super().__init__(**kwargs)
        self.sensor_code = sensor_code
        self.col_name = col_name
        self.options = [ft.dropdown.Option(text) for text in dropdown_list]
        self.on_change = self.on_change_tread
        if not default_value:
            self.value = dropdown_list[0]
        self.on_change = self.on_change

    def on_change_tread(self, e):
        setattr(ProjectInfo.sensor_info_dict[self.sensor_code], self.col_name, e.data)


def data_to_line_chart_point(data_dict: dict):
    index = ProjectInfo.line_chart_index
    angle_data = calculate_angle(data_dict)
    a_angel = data_dict["a"]
    b_angel = data_dict["b"]

    ProjectInfo.acc_a_x_line_chart_list.append(ft.LineChartDataPoint(index, a_angel["acc_x"]))
    ProjectInfo.acc_a_y_line_chart_list.append(ft.LineChartDataPoint(index, a_angel["acc_y"]))
    ProjectInfo.acc_a_z_line_chart_list.append(ft.LineChartDataPoint(index, a_angel["acc_z"]))

    ProjectInfo.acc_b_x_line_chart_list.append(ft.LineChartDataPoint(index, b_angel["acc_x"]))
    ProjectInfo.acc_b_y_line_chart_list.append(ft.LineChartDataPoint(index, b_angel["acc_y"]))
    ProjectInfo.acc_b_z_line_chart_list.append(ft.LineChartDataPoint(index, b_angel["acc_z"]))

    ProjectInfo.a_agree_line_chart_list.append(ft.LineChartDataPoint(index, angle_data["a_angel"]))
    ProjectInfo.b_agree_line_chart_list.append(ft.LineChartDataPoint(index, angle_data["b_angel"]))
    ProjectInfo.total_line_chart_list.append(ft.LineChartDataPoint(index, angle_data["total_angle"]))

    ProjectInfo.line_chart_index += 1
    print("坐标是")
    print(f"index:{index}, a_angle:{angle_data["a_angel"]}")
    print(f"a的角度值数量是:{len(ProjectInfo.a_agree_line_chart_list)}")
    return angle_data
